package com.net.xpay.common.service.impl;

import com.net.xpay.common.domain.User;
import com.net.xpay.common.domain.UserShard;
import com.net.xpay.common.domain.stat.PartnerUserRealTimeStat;
import com.net.xpay.common.manager.UserManager;
import com.net.xpay.common.manager.UserShardManager;
import com.net.xpay.common.manager.stat.PartnerUserRealTimeStatManager;
import com.net.xpay.common.model.search.UserSearchModel;
import com.net.xpay.core.manager.ChargeRecordManager;
import com.net.xpay.core.manager.PayTransBatchManager;
import com.net.xpay.core.manager.safePay.SafePayBatchManager;
import com.net.xpay.core.model.PartnerUserPayTransDayStatModel;
import com.net.xpay.core.model.PartnerUserSafePayTransDayStatModel;
import com.net.common.util.LocalDateUtil;
import com.net.xpay.common.service.PartnerUserRealTimeStatService;
import com.net.shard.ShardUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class PartnerUserRealTimeStatServiceImpl implements PartnerUserRealTimeStatService {

    @Autowired
    private UserManager userManager;

    @Autowired
    private UserShardManager userShardManager;

    @Autowired
    private ChargeRecordManager chargeRecordManager;

    @Autowired
    private PayTransBatchManager payTransBatchManager;

    @Autowired
    private SafePayBatchManager safePayBatchManager;

    @Autowired
    private PartnerUserRealTimeStatManager partnerUserRealTimeStatManager;

    @Override
    public void statPartnerUserRealTimeStat(LocalDateTime time) {
        UserSearchModel searchModel = new UserSearchModel();
        List<Long> userIds = userManager.listIds(searchModel);

        log.info("statPartnerUserRealTimeStat userIds={}", userIds);
        if (CollectionUtils.isEmpty(userIds)) {
            return;
        }
        for (Long userId : userIds) {
            try {
                doPartnerUserRealTimeStat(userId, time);
            } catch (Exception e) {
                log.error("statPartnerUserRealTimeStat error|userId={}", userId, e);
            }
        }
    }

    @Override
    public void doPartnerUserRealTimeStat(Long userId, LocalDateTime maxEndTime) {
        User user = userManager.getById(userId);
        if (user.getPartnerId() == null) {
            //没有合伙人的不统计
            return;
        }

        // 通过userID获取到userShard
        UserShard userShard = userShardManager.getById(userId);
        try {
            // 切库处理
            ShardUtil.setShardContext(userShard.getShardId());
            //初始化
            PartnerUserRealTimeStat stat = PartnerUserRealTimeStat.getInstance(userId, user.getPartnerId(),maxEndTime);
            // 获取当天的起始时间和终止时间 终止时间保留在当前时间
            LocalDateTime minEndTime = LocalDateUtil.getDayStart(maxEndTime);
            //统计查询
            //chargeRecord表统计
            long serviceChargeFee = chargeRecordManager.sumUserServiceChargeFeeByDay(user.getId(),minEndTime,maxEndTime);
            //payTransBatch表统计
            PartnerUserPayTransDayStatModel partnerUserPayTransDayStatModel = payTransBatchManager.sumPartnerUserPayTransDay(user.getId(),minEndTime,maxEndTime);
            //safePayTransBatch表统计
            PartnerUserSafePayTransDayStatModel safePayTransDayStatModel = safePayBatchManager.sumPartnerUserSafePayTransDay(user.getId(),minEndTime,maxEndTime);

            stat.setServiceChargeFee(new BigDecimal(serviceChargeFee).multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.HALF_UP));

            stat.setPayTransCount(partnerUserPayTransDayStatModel.getPayTransCount());
            stat.setPayTransSuccessCount(partnerUserPayTransDayStatModel.getPayTransSuccessCount());
            stat.setPayTransFailCount(partnerUserPayTransDayStatModel.getPayTransFailCount());
            stat.setPayTransServicePrice(new BigDecimal(partnerUserPayTransDayStatModel.getPayTransServicePrice()).multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.HALF_UP));
            stat.setPayTransAmount(partnerUserPayTransDayStatModel.getPayTransAmount());
            stat.setPayTransSuccessAmount(partnerUserPayTransDayStatModel.getPayTransSuccessAmount());
            stat.setPayTransFailAmount(partnerUserPayTransDayStatModel.getPayTransFailAmount());
            stat.setTotalPayTransPartnerBenefit(new BigDecimal(partnerUserPayTransDayStatModel.getTotalPayTransPartnerBenefit()).multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.HALF_UP));

            stat.setSafePayTransCount(safePayTransDayStatModel.getSafePayTransCount());
            stat.setSafePayTransSuccessCount(safePayTransDayStatModel.getSafePayTransSuccessCount());
            stat.setSafePayTransFailCount(safePayTransDayStatModel.getSafePayTransFailCount());
            stat.setSafePayTransAmount(safePayTransDayStatModel.getSafePayTransAmount());
            stat.setSafePayTransSuccessAmount(safePayTransDayStatModel.getSafePayTransSuccessAmount());
            stat.setSafePayTransFailAmount(safePayTransDayStatModel.getSafePayTransFailAmount());
            stat.setSafePayTransServicePrice(new BigDecimal(safePayTransDayStatModel.getSafePayTransServicePrice()).multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.HALF_UP));
            stat.setTotalSafePayTransPartnerBenefit(new BigDecimal(safePayTransDayStatModel.getTotalSafePayTransPartnerBenefit()).multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.HALF_UP));

            //总和数据入库
            stat.setTotalCount(stat.getPayTransCount() + stat.getSafePayTransCount());
            stat.setTotalSuccessCount(stat.getPayTransSuccessCount() + stat.getSafePayTransSuccessCount());
            stat.setTotalFailCount(stat.getPayTransFailCount() + stat.getSafePayTransFailCount());

            stat.setTotalServicePrice(stat.getPayTransServicePrice().add(stat.getSafePayTransServicePrice()));

            stat.setTotalTransAmount(stat.getPayTransAmount().add(stat.getSafePayTransAmount()));
            stat.setTotalSuccessTransAmount(stat.getPayTransSuccessAmount().add(stat.getSafePayTransSuccessAmount()));
            stat.setTotalFailTransAmount(stat.getPayTransFailAmount().add(stat.getSafePayTransFailAmount()));

            stat.setTotalPartnerBenefit(stat.getTotalPayTransPartnerBenefit().add(stat.getTotalSafePayTransPartnerBenefit()));

            PartnerUserRealTimeStat beforeStat = partnerUserRealTimeStatManager.getByUserId(userId);
            if (beforeStat != null) {
                stat.setId(beforeStat.getId());
                partnerUserRealTimeStatManager.update(stat);
            } else {
                partnerUserRealTimeStatManager.save(stat);
            }

        } finally {
            ShardUtil.cleanShardContext();
        }
    }


}
